#include <REGX52.h>
#include "Delay.h"

sbit I2C_SDA = P2^0;//数据线
sbit I2C_SCL = P2^1;//Clock线

/**
  * @brief		I2C开始标志
  * @parm		无
  * @retval		无
  */
void I2C_Start()
{
	//起始条件：SCL高电平期间，SDA从高电平切换到低电平
	//先置SDA = 1，确保从高电平切到低电平
	I2C_SDA = 1;
	//SCL置高电平
	I2C_SCL = 1;
	//SDA由高电平切换为低电平
	I2C_SDA = 0;
	//SCL恢复低电平
	I2C_SCL = 0;
}
/**
  * @brief		I2C停止标志
  * @parm		无
  * @retval		无
  */
void I2C_Stop()
{
	//终止条件：SCL高电平期间，SDA从低电平切换到高电平
	//先置SDA = 0，确保从低电平切到高电平
	I2C_SDA = 0;
	//SCL置高电平
	I2C_SCL = 1;
	//SDA由低电平切换为高电平
	I2C_SDA = 1;
}
/**
  * @brief		I2C发送字节数据
  * @parm		Byte：要发送的数据，范围: 0 ~ 255
  * @retval		无
  */
void I2C_SendByte(unsigned char Byte)
{
	//发送数据：从高位开始
	//SCL低电平期间，SDA写数据，SCL拉高后，从机读取数据
	unsigned char i = 0;
	for(i = 0; i < 8; ++i)
	{
		I2C_SDA = Byte & (0x80 >> i);
		I2C_SCL = 1;//此处要注意若机器频率过快，可能导致从机还没读到数据，SCL就被拉低了
		I2C_SCL = 0;//需要查看手册。
	}
}
/**
  * @brief		I2C读取一字节数据
  * @parm		无
  * @retval		读取到的数据
  */
unsigned char I2C_ReceiveByte()
{
	//接收数据，从高位开始
	//SCL高电平时，从SDA读数据
	unsigned char Byte = 0, i;
	//将SDA置高电平，释放SDA给从机
	I2C_SDA = 1;
	for(i = 0; i < 8; ++i)
	{
		I2C_SCL = 1;
		if(I2C_SDA)	Byte |= (0x80 >> i);
		I2C_SCL = 0;
	}
	return Byte;
}
/**
  * @brief		发送应答
  * @parm		AckBit为0表示应答，为1表示非应答
  * @retval		无
  */
void I2C_SendAck(unsigned char AckBit)
{
	//在读完一个字节后，主机在下一个时钟发送一位数据
	//数据0表示应答，数据1表示非应答
	I2C_SDA = AckBit;
	I2C_SCL = 1;
	I2C_SCL = 0;
}
/**
  * @brief		接收应答
  * @parm		无
  * @retval		Ack为0表示应答，为1表示非应答
  */
unsigned char I2C_ReceiveAck()
{
	//在发完一个字节后，主机在下一个时钟接收一位数据，判断从机是否应答
	//数据0表示应答，数据1表示非应答（主机在接收之前，需要释放SDA）
	unsigned char Ack;
	//释放SDA
	I2C_SDA = 1;
	//SCL置高电平
	I2C_SCL = 1;
	//读响应
	Ack = I2C_SDA;
	//SCL置低电平
	I2C_SCL = 0;
	return Ack;
}
